/*
 * Axelor Business Solutions
 *
 * Copyright (C) 2005-2021 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.axelor.tools.x2j.pojo

import groovy.transform.CompileStatic


/**
 * This class provides naming utilities for code generator.
 *
 */
@CompileStatic
final class Naming {

  private Naming() {
  }

  /**
   * Check whether the given name is a reserved keyword.
   *
   */
  public static boolean isReserved(String name) {
    return RESERVED_JAVA.contains(name) || RESERVED_EXTRA.contains(name);
  }

  /**
   * Check whether the given name is SQL reserved keyword.
   *
   */
  public static boolean isKeyword(String name) {
    return RESERVED_POSTGRESQL.contains(name) ||
        RESERVED_MYSQL.contains(name) ||
        RESERVED_ORACLE.contains(name);
  }

  /**
   * Quote the given column name.
   *
   */
  public static String quoteColumn(String name) {
    return "`" + name + "`"
  }

  // Internal Reserved
  private static final Set<String> RESERVED_EXTRA = new LinkedHashSet<>([
    "version",
    "archived",
    "selected",
    "constructor"
  ])

  // Java Keywords
  private static final Set<String> RESERVED_JAVA = new LinkedHashSet<>([
    "abstract",
    "assert",
    "boolean",
    "break",
    "byte",
    "case",
    "catch",
    "char",
    "class",
    "const",
    "continue",
    "default",
    "do",
    "double",
    "else",
    "enum",
    "extends",
    "final",
    "finally",
    "float",
    "for",
    "goto",
    "if",
    "implements",
    "import",
    "instanceof",
    "int",
    "interface",
    "long",
    "native",
    "new",
    "package",
    "private",
    "protected",
    "public",
    "return",
    "short",
    "static",
    "strictfp",
    "super",
    "switch",
    "synchronized",
    "this",
    "throw",
    "throws",
    "transient",
    "try",
    "void",
    "volatile",
    "while"
  ]);

  // PostgreSQL 9.x
  private static final Set<String> RESERVED_POSTGRESQL = new LinkedHashSet<>([
    "all",
    "analyse",
    "analyze",
    "and",
    "any",
    "array",
    "as",
    "asc",
    "asymmetric",
    "both",
    "case",
    "cast",
    "check",
    "collate",
    "column",
    "constraint",
    "create",
    "current_catalog",
    "current_date",
    "current_role",
    "current_time",
    "current_timestamp",
    "current_user",
    "default",
    "deferrable",
    "desc",
    "distinct",
    "do",
    "else",
    "end",
    "except",
    "false",
    "fetch",
    "for",
    "foreign",
    "from",
    "grant",
    "group",
    "having",
    "in",
    "initially",
    "intersect",
    "into",
    "lateral",
    "leading",
    "limit",
    "localtime",
    "localtimestamp",
    "not",
    "null",
    "offset",
    "on",
    "only",
    "or",
    "order",
    "placing",
    "primary",
    "references",
    "returning",
    "select",
    "session_user",
    "some",
    "symmetric",
    "table",
    "then",
    "to",
    "trailing",
    "true",
    "union",
    "unique",
    "user",
    "using",
    "variadic",
    "when",
    "where",
    "window",
    "with"
  ]);

  // MariaDB 10.x & MySQL 5.5
  private static final Set<String> RESERVED_MYSQL = new LinkedHashSet<>([
    "accessible",
    "add",
    "all",
    "alter",
    "analyze",
    "and",
    "as",
    "asc",
    "asensitive",
    "before",
    "between",
    "bigint",
    "binary",
    "blob",
    "both",
    "by",
    "call",
    "cascade",
    "case",
    "change",
    "char",
    "character",
    "check",
    "collate",
    "column",
    "condition",
    "constraint",
    "continue",
    "convert",
    "create",
    "cross",
    "current_date",
    "current_time",
    "current_timestamp",
    "current_user",
    "cursor",
    "database",
    "databases",
    "day_hour",
    "day_microsecond",
    "day_minute",
    "day_second",
    "dec",
    "decimal",
    "declare",
    "default",
    "delayed",
    "delete",
    "desc",
    "describe",
    "deterministic",
    "distinct",
    "distinctrow",
    "div",
    "double",
    "drop",
    "dual",
    "each",
    "else",
    "elseif",
    "enclosed",
    "escaped",
    "exists",
    "exit",
    "explain",
    "false",
    "fetch",
    "float",
    "float4",
    "float8",
    "for",
    "force",
    "foreign",
    "from",
    "fulltext",
    "grant",
    "group",
    "having",
    "high_priority",
    "hour_microsecond",
    "hour_minute",
    "hour_second",
    "if",
    "ignore",
    "in",
    "index",
    "infile",
    "inner",
    "inout",
    "insensitive",
    "insert",
    "int",
    "int1",
    "int2",
    "int3",
    "int4",
    "int8",
    "integer",
    "interval",
    "into",
    "is",
    "iterate",
    "join",
    "key",
    "keys",
    "kill",
    "leading",
    "leave",
    "left",
    "like",
    "limit",
    "linear",
    "lines",
    "load",
    "localtime",
    "localtimestamp",
    "lock",
    "long",
    "longblob",
    "longtext",
    "loop",
    "low_priority",
    "master_ssl_verify_server_cert",
    "match",
    "maxvalue",
    "mediumblob",
    "mediumint",
    "mediumtext",
    "middleint",
    "minute_microsecond",
    "minute_second",
    "mod",
    "modifies",
    "natural",
    "not",
    "no_write_to_binlog",
    "null",
    "numeric",
    "on",
    "optimize",
    "option",
    "optionally",
    "or",
    "order",
    "out",
    "outer",
    "outfile",
    "precision",
    "primary",
    "procedure",
    "purge",
    "range",
    "read",
    "reads",
    "read_write",
    "real",
    "references",
    "regexp",
    "release",
    "rename",
    "repeat",
    "replace",
    "require",
    "resignal",
    "restrict",
    "return",
    "revoke",
    "right",
    "rlike",
    "schema",
    "schemas",
    "second_microsecond",
    "select",
    "sensitive",
    "separator",
    "set",
    "show",
    "signal",
    "smallint",
    "spatial",
    "specific",
    "sql",
    "sql_big_result",
    "sql_calc_found_rows",
    "sqlexception",
    "sql_small_result",
    "sqlstate",
    "sqlwarning",
    "ssl",
    "starting",
    "straight_join",
    "table",
    "terminated",
    "then",
    "tinyblob",
    "tinyint",
    "tinytext",
    "to",
    "trailing",
    "trigger",
    "true",
    "undo",
    "union",
    "unique",
    "unlock",
    "unsigned",
    "update",
    "usage",
    "use",
    "using",
    "utc_date",
    "utc_time",
    "utc_timestamp",
    "values",
    "varbinary",
    "varchar",
    "varcharacter",
    "varying",
    "when",
    "where",
    "while",
    "with",
    "write",
    "xor",
    "year_month",
    "zerofill"
  ])

  // Oracle
  private static final Set<String> RESERVED_ORACLE = new LinkedHashSet<String>([
    "access",
    "add",
    "all",
    "alter",
    "and",
    "any",
    "arraylen",
    "as",
    "asc",
    "audit",
    "between",
    "by",
    "char",
    "check",
    "cluster",
    "column",
    "comment",
    "compress",
    "connect",
    "create",
    "current",
    "date",
    "decimal",
    "default",
    "delete",
    "desc",
    "distinct",
    "drop",
    "else",
    "exclusive",
    "exists",
    "file",
    "float",
    "for",
    "from",
    "grant",
    "group",
    "having",
    "identified",
    "immediate",
    "in",
    "increment",
    "index",
    "initial",
    "insert",
    "integer",
    "intersect",
    "into",
    "is",
    "level",
    "like",
    "lock",
    "long",
    "maxextents",
    "minus",
    "mode",
    "modify",
    "noaudit",
    "nocompress",
    "not",
    "notfound",
    "nowait",
    "null",
    "number",
    "of",
    "offline",
    "on",
    "online",
    "option",
    "or",
    "order",
    "pctfree",
    "prior",
    "privileges",
    "public",
    "raw",
    "rename",
    "resource",
    "revoke",
    "row",
    "rowid",
    "rowlabel",
    "rownum",
    "rows",
    "select",
    "session",
    "set",
    "share",
    "size",
    "smallint",
    "sqlbuf",
    "start",
    "successful",
    "synonym",
    "sysdate",
    "table",
    "then",
    "to",
    "trigger",
    "uid",
    "union",
    "unique",
    "update",
    "user",
    "validate",
    "values",
    "varchar",
    "varchar2",
    "view",
    "whenever",
    "where",
    "with"
  ]);
}
